package csl.blog.server.config.thread;

import csl.blog.server.config.thread.base.QuickTaskDecorator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @Description: TODO 配置线程池
 * @author: 隔山海
 * @date: 2022年03月26日 0:34
 */
@Slf4j
//@Configuration
public class ThreadPoolConfig {

    @Value("${threadPool.upload.corePoolSize}")
    private int uploadCorePoolSize;

    @Value("${threadPool.upload.maxPoolSize}")
    private int uploadMaxPoolSize;

    @Value("${threadPool.upload.keepAliveSeconds}")
    private int uploadKeepAliveSeconds;

    @Value("${threadPool.upload.queueCapacity}")
    private int uploadQueueCapacity;

    @Value("${threadPool.upload.threadNamePrefix}")
    private String uploadThreadNamePrefix;

    @Value("${threadPool.quick.corePoolSize}")
    private int quickCorePoolSize;

    @Value("${threadPool.quick.maxPoolSize}")
    private int quickMaxPoolSize;

    @Value("${threadPool.quick.keepAliveSeconds}")
    private int quickKeepAliveSeconds;

    @Value("${threadPool.quick.queueCapacity}")
    private int quickQueueCapacity;

    @Value("${threadPool.quick.threadNamePrefix}")
    private String quickThreadNamePrefix;

    /**
     * 上传异步任务
     */
//    @Bean(name = "uploadExecutor")
    public ThreadPoolExecutor uploadExecutor() {
        log.info("initialization uploadExecutor........");
        return new ThreadPoolExecutor(
                uploadCorePoolSize,
                uploadMaxPoolSize,
                uploadKeepAliveSeconds, TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(uploadQueueCapacity),
                new CustomizableThreadFactory(uploadThreadNamePrefix),
                new ThreadPoolExecutor.CallerRunsPolicy());
    }

    /**
     * 快速处理批量任务型，吞吐量优先使用LinkedBlockingQueue
     */
//    @Bean(name = "asyncQuickExecutor")
    public ThreadPoolTaskExecutor asyncQuickExecutor() {
        log.info("initialization asyncQuickExecutor........");
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setCorePoolSize(quickCorePoolSize);
        threadPoolTaskExecutor.setMaxPoolSize(quickMaxPoolSize);
        threadPoolTaskExecutor.setQueueCapacity(quickQueueCapacity);
        threadPoolTaskExecutor.setKeepAliveSeconds(quickKeepAliveSeconds);
        threadPoolTaskExecutor.setThreadNamePrefix(quickThreadNamePrefix);
        threadPoolTaskExecutor.setTaskDecorator(new QuickTaskDecorator());
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor;
    }

}
